#pragma once
#include<iostream>
#include"util.hpp"
#include <fstream>
#include<sstream>
#include<cassert>
#include<memory>
#include<ctime>
//日志消息落地方向控制
namespace logs
{

    class sink
    {
    public:
        using ptr = std::shared_ptr<sink>;
        virtual void log(const char* dst,size_t size) = 0;
    };
    //标准输入输出
    class Stdoutsink:public sink
    {
    public:
        void log(const char* dst,size_t size)override
        {
            std::cout.write(dst,size);
        }
    };

    class Filesink:public sink
    {
    public:
        Filesink(const std::string& pathname)
        :_pathname(pathname)
        {
             util::file::CreateDreactor(util::file::pathname(_pathname));//创建文件
            //打开并写入
            //这里应该用类内成员,而不是定义局部变量
            _ofs.open(_pathname,std::ofstream::binary | std::ofstream::app);
            assert(_ofs.is_open());
        }
        void log(const char* dst,size_t size)override
        {
            _ofs.write(dst,size);
            assert(_ofs.good());
        }
        std::string _pathname;
        std::ofstream _ofs;
    };
    
    class Rollsink:public sink
    {
    public:
        Rollsink(const std::string& basename,int max_size)
        :_basename(basename)
        ,_filename(basename)
        ,_max_size(max_size)
        {
            CreateNewfile();//构建文件名
            util::file::CreateDreactor(util::file::pathname(_filename));//创建文件
            _ofs.open(_filename,std::ofstream::binary | std::ofstream::app);
            assert(_ofs.is_open());
        }
        void log(const char* dst,size_t size)override
        {
            if(_cur_size >= _max_size)
            {
                _ofs.close();
                CreateNewfile();
                _cur_size = 0;
                _ofs.open(_filename,std::ofstream::binary | std::ofstream::app); 
                assert(_ofs.is_open());
            }
            //打开并写入
            _ofs.write(dst,size);
            _cur_size += size;
            assert(_ofs.good());
        }
        void CreateNewfile()
        {
            std::stringstream sst;
            sst<< _basename;
            struct tm st;
            const time_t t = time(nullptr);
            localtime_r(&t,&st);
            sst<< st.tm_year+1900;
            sst<< st.tm_mon+1;
            sst<< st.tm_mday;
            sst<< "->";
            sst<<_count++;
            // std::cout<<_count<<std::endl;
            _filename = sst.str();
        }
        int _count = 0;
        std::ofstream _ofs;
        std::string _filename;
        std::string _basename;
        int _max_size;
        int _cur_size = 0;
    };
    //创建上面的日志落地类
    class Factorysink
    {
    public:
        template<typename T,typename ...Args>
        static std::shared_ptr<T> Create(Args&& ...args)
        {
           return  std::make_shared<T>(std::forward<Args>(args)...);
        }
    };
};